/**
 * Media Capabilities API
 *    首先要说的是当前（2019-03-19），该 API 还不是 W3C 标准，也不在 W3C 标准储备中，
 * 本规格是由网络平台孵化器社区小组发布的，所以当前的兼容性等于没有，暂时只有 Chrome 系列平台和 FireFox 在较新版本支持。
 * 学习本规格主要是了解为主。
 * 
 * 摘要：
 *    本规格旨在提供 API 让网站在为用户提供媒体内容时，可以做出最佳选择。
 * API 会给出一些关于为指定格式的媒体内容编解码时的信息，也提供能力来基于设备显示指标找到最佳适配。
 * 
 *    上面的摘要说的比较模糊，让我们更详细地说明本规格定义的内容。
 * 我们知道存在数量众多的多媒体数据编解码器（codecs），不同的浏览器支持不同的媒体类型，并且不断有新的媒体类型被发开出来。
 * 使用 Media Capabilities API，开发者可以保证每个用户都得到最佳的比特率并且为浏览器、设备和操作系统节省存储。
 *    
 *    设备使用硬件解码还是软件解码会影响音视频解码时的流畅性和效率，也会影响播放效率。
 * 使用 Media Capabilities API 可以决定应该支持哪一个编解码器的问题，同事可以知到一个媒体文件在流畅性和效率上的性能。
 * 
 *    Media Capabilities API 提供了比 MediaSource.isTypeSupported() 和 HTMLMediaElement.canPlayType() 更强力的方法，
 * 原来这两个方法只能浏览器是否支持当前类型，而无关于性能。同时 API 还提供了访问显示设备信息的能力，比如支持的色阶、动态范围和播放实时反馈等。（暂无任何浏览器支持）
 * 
 *    想要调用这些能力，我们需要定义一个 mediaConfiguration 对象，并作为 navigator.MediaCapabilities 对象下，
 * encodingInfo() 和 decodingInfo() 方法的参数。
 * 
 *    进一步讲，媒体能力信息让网站可以启动一个自适应流，来根据用户的真实体验质量修改播放质量，并且对 CPU/GPU 使用情况作出实时反馈。
 */

/**
 * 通过上面的介绍基本了解了本 API 提供的能力，下面正式学习API的数据字典。
 * 
 * MediaConfiguration 字典：{
 *    video: {VideoConfiguration}，可为空，但不能同时为空
 *    audio: {AudioConfiguration}，可为空，但不能同时为空
 * }
 * 
 * 用于解码信息的配置对象
 * MediaDecodingConfiguration : MediaConfiguration 字典：{
 *    type: {MediaDecodingType}，这个配置要表示的媒体源类型
 *    keySystemConfiguration: { MediaCapabilitiesKeySystemConfiguration}
 * }
 * enum MediaDecodingType 字典：{
 *    "file": 表示这个配置意味着播放一个扁平文件
 *    "media-source": 表示这个配置意味着播放一个 MediaSource 对象。
 * }
 * 
 * 用于编码信息的配置对象
 * MediaEncodingConfiguration : MediaConfiguration 字典：{
 *    "type": {MediaEncodingType}
 * }
 * enum MediaEncodingType 字典：{
 *    "record": 用于表示录制媒体的配置
 *    "transmission": 用于表示通过电子方式传输的配置
 *    // 这二者的区别在于它们用于的对象不同，"record"用在[ mediastream-recording ]规格定义的 MediaRecorder 对象上，而“transmission”用于 RTCPeerConnection 对象上。
 * }
 * 
 * // 视频配置参数对象
 * VideoConfiguration 字典：{
 *    contentType: {string}，预期适配的 MIME 类型，可以带一个参数用于指定解码器 video/webm;codec=vp8
 *    width: {unsigned long}，
 *    height: {unsigned long}，width 和 height 分别表示要编码的视频帧上水平和竖直方向的要编码的像素数
 *    bitrate: 视频轨的平局比特率，单位比特/秒。在使用固定比特率的场景下，应该在短期内精确。在使用可变比特率时，要保证这个值能用于调整缓冲和吞吐量，以便根据指定的ContentType在长期内提供视频流的无中断解码。
 *    framerate: 每秒使用的帧数。
 * }
 * 
 * // 音频配置参数对象
 * AudioConfiguration 字典：{
 *    contentType: {string}，与视频配置类似，不过 MIME 类型应该对应音频文件
 *    channels: {string}，表示音频轨道用到的音频通道
 *    bitrate: {unsigned long long}，音频轨道的平均比特率，表示音频轨道每秒编码的位数
 *    samplerate: {unsigned long long}，音频轨道的采样频率，表示音频轨道每秒的采样次数，单位是Hz
 * }
 * 
 * 这个数据字典内部的字段俊宇 EME 规格相关，是解码用的密钥系统
 * MediaCapabilitiesKeySystemConfiguration 字典 {
 *    keySystem: {string}，密钥系统名
 *    initDataType: {string}，initDataTypes 中的一项
 *    audioRobutness: {string}，音频的鲁棒性
 *    videoRobutness: {string}，视频的鲁棒性
 *    distinctiveIdentifier: {MedaiKeysRequirement}，特殊标识符
 *    persistentState: {MedaiKeysRequirement}，固定状态
 *    sessionType: {Array<string>}，密钥会话类型
 * }
 * 
 * 下面这个数据字典是 encodingInfo 和 decodingInfo 函数返回的Promise中携带的数据类型，也是本 API 中最常用的类型
 * MediaCapabilitiesInfo 字典：{
 *    supported: {boolean}，是否支持配置参数中给出的 MIME 类型
 *    smooth: {boolean}，按照配置参数中给出的条件能否流畅播放
 *    powerEfficient: {boolean}，按照配置参数中给出的条件，能否保持高效
 * }
 * MediaCapabilitiesDecodingInfo : MediaCapabilitiesInfo {
 *    keySystemAccess: {MediaKeySystemAccess}，对应解密系统的解密系统访问对象
 * }
 */

/**
 * 上面洋洋洒洒，的各类接口均实现在本 API 内部，最终本 API 暴露的的调用入口在 navigator 对象上（如果是 Wroker 环境中，则在 WrokerNavigator 对象上）
 * MediaCapabilities 字典：{
 *    decodingInfo: {Function(MediaDecodingConfiguration configuration)}，返回 Promise<MediaCapabilitiesDecodingInfo>
 *    encodingInfo: {Function(MediaEncodingConfiguration configuration)}，返回 Promise<MediaCapabilitiesInfo>
 * }
 */

/**
 * 事实上，本规格还定义了显示能力（display Capability），描述显示设备（屏幕）的基本数据，但暂无浏览器实现
 * 屏幕亮度字典
 * ScreenLuminance 字典：{
 *    min: {double}，只读，最小亮度
 *    max: {double}，只读，最大亮度
 *    maxAverage: {double}，只读，最大平均值
 * }
 * 屏幕色阶
 * enum ScreenColorGamut 字典：{
 *    "srgb", "p3", "rec2020" 从右向左是一次包含的关系
 * }
 * 以上两个数据字典均包含在 Screen 接口的扩展属性中
 * Screen {
 *    colorGamut: {ScreenColorGamut}
 *    luminance: {ScreenColorGamut}
 * }
 */

// 最后在最新版 Chrome 下体验一下获取编码信息的方法
const configuration = {
  type: 'record',
  video: {
    contentType: 'video/webm;codecs=vp8',
    width: 640,
    height: 480,
    bitrate: 10000,
    framerate: '30'
  }
};

// 事实上，现在 Chrome 默认吧 encodingInfo 方法禁用了，需要手动打开 chrome://flags/#enable-experimental-web-platform-features
// 可惜我没找到...
navigator.mediaCapabilities.encodingInfo(configuration)
  .then(result => {
    console.log(`${result.contentType} is: ${result.supported ? '' : 'Not'} supported, ${result.smooth ? '' : 'Not'} smooth and ${result.powerEfficient ? '' : 'Not'} power efficient.`);
  })
  .catch(e => {
    console.error(e);
  })